/* "qDroid v.2009.04.27 pre-alfa-2"
 * qdl_ChildProcess.h
 *
 *  Created on: 2009.09.09
 *      Author: Denjs

 * UTF-8 encoded
 * Класс для запуска дочернего процесса. QDroid-оболочка, потомок QProcess

*/

// ТРЕБУЕТ ЗАГРУЖЕННОГО РАСШИРЕНИЯ "BYTEARRAY"

/*
 * замените "ChildProcess" на имя вашего класса здесь,
 * и исходнике класса qdl_ChildProcess.cpp,
 * и переименуйте файлы данного класса соответвующим образом.
 * Не забудьте про "ChildProcess_H_"
 * Не забудьте про замену ссылки на конструктор родителя в конструкторе (в .cpp-файле)
 *
 * Не забудьте, что только "слотовые" функции могут быть вызваны из скрипта.
 *
 * Возможно
 */

#ifndef ChildProcess_H_
#define ChildProcess_H_

#include <QtCore>
#include <QApplication>
#include <QtScript>
/*::[[@childprocess]] [[:qdroid_classes]]
 Класс для запуска дочернего процесса. QDroid-оболочка, потомок QProcess \n 

**childprocess** - класс для работы с потоками STDIN|STDOUT|STDERR. \n 
См также:
  * [[stdinreader]] (класс для рабаоты с потоками ввода-ввыода);

====Общие характеристики====
  * имя конструктора QtScript: ChildProcess ;
  * C++ имя класса : qdl_ChildProcess наследован от QProcess ;
  * Являетля классом, предоставляемым расширением.[[qdlib_childprocess]]
  * Требует для нормальной работы загруженного расширения : [[qdlib_bytearray]]

====Методы и свойства класса====
*/

class qdl_ChildProcess : public QProcess //::====$0 $1====\n  * **$**** 
{
    Q_OBJECT

public: //::===Секция $* (С++)===
	qdl_ChildProcess(); //::  * **$*** \n Конструктор
	virtual ~qdl_ChildProcess(); //::  * **$*** \n Деструктор

    	//это (ниже) нужно что бы можно было засунуть класс в контейнер QList
    	// возможно так-же связано с работой QtScript движка - см функции
		// после определения класса
		//
    	// спец. настройки для QtScript (v 2008.11.25)
    	// Шаг 1 из 8
    	qdl_ChildProcess(const qdl_ChildProcess &other); //::  * **$*** \n Конструктор копирования 

    	//это (ниже) нужно что бы можно было засунуть t_FileList в контейнер QList
    	// возможно так-же связано с работой QtScript движка - см функции
    	// после определения класса
    	//
    	// спец. настройки для QtScript (v 2008.11.25)
    	// Шаг 2 из 8
    	qdl_ChildProcess& operator=(const qdl_ChildProcess &other);//::  * **$*** \n Определение операции сравнения.

    	// спец. настройки для QtScript (v 2008.11.25)
    	// Шаг 2.2 из 8
	bool operator==(const qdl_ChildProcess &other ) const;//::  * **$*** \n Определение операции сравнения.


public slots: //::===Секция $* (С++\QtScript)===
	QString GetId(); //::  * **$*** \nПолучить идентификатор объекта. (класс, версия, дата, время создания).

        //:: далее - перенаследуем в слоты кое-какие функции которые будут нам нужны в скриптах.
	//QProcess` Public Functions
	void start(QString program); //::  * **$*** \n Запустить дочерний процесс
	void closeWriteChannel(); //::  * **$*** \n Закрыть стандартный поток записи данных в дочерний процесс.
//	void closeReadChannel();
	void close(); //::  * **$*** \n Закрыть дочерний процесс.

	QStringList environment () const; //::  * **$*** \n Получить список переменных окружения
	int error () const; //::  * **$*** \n получить  код ошибки запуска/завершения дочерненго процесса. Генерируется системой, если произошла ошибка.<br>
		//::коды ошибок повторяют перечисление
		//::enum QProcess::ProcessError
		//::^Constant ^Value ^Description ^
		//::|QProcess::FailedToStart | 0 | The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.|
		//::|QProcess::Crashed | 1 | The process crashed some time after starting successfully.|
		//::|QProcess::Timedout | 2 | The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again.|
		//::|QProcess::WriteError | 4 | An error occurred when attempting to write to the process. For example, the process may not be running, or it may have closed its input channel.|
		//::|QProcess::ReadError | 3 | An error occurred when attempting to read from the process. For example, the process may not be running.|
		//::|QProcess::UnknownError | 5 | An unknown error occurred. This is the default return value of error().|
		//:: 
	int exitCode() const; //::  * **$*** \n код завершения процесса который вернул процесс.


	int exitStatus () const; //::  * **$*** \n Статус завершения процесса. Ошибка или нормальное завершение.
	//:: <br> Значение статуса соответсвует перечислению QProcess::ExitStatus: 
	//::^Constant ^Value ^Description ^
	//::|QProcess::NormalExit | 0 | The process exited normally. |
	//::|QProcess::CrashExit | 1 | The process crashed. |
	
	QByteArray readAllStandardError(); //::  * **$*** \n прочитать весь стандартный поток вывода ошибок дочернего процесса. <br>
		//:: Иногда вывод дочернего процесса заносится в буфер и не становится доступно родительскому процессу сразу. Данная функцкция принудительно читает быфер. 
	QByteArray readAllStandardOutput();//::  * **$*** \n прочитать весь стандартный поток вывода дочернего процесса. <br>
		//:: Иногда вывод дочернего процесса заносится в буфер и не становится доступно родительскому процессу сразу. Данная функцкция принудительно читает быфер. 

	void setEnvironment ( const QStringList & environment ); //::* $* | Установить переменные окружения


	//  void start ( const QString & program, const QStringList & arguments );
	//void startProcess ( const QString & program );

		
	int state () const; //::  * **$*** \n 
		//:: соответсвует перечислению QProcess::ProcessState:
		//::^Constant ^Value ^Description ^
		//::|QProcess::NotRunning | 0 | The process is not running. |
		//::|QProcess::Starting | 1 | The process is starting, but the program has not yet been invoked |
		//::|QProcess::Running | 2 | The process is running and is ready for reading and writing. |
		//:: 
	bool waitForFinished ( int msecs = 30000 );//::  * **$*** \n 
	bool waitForStarted ( int msecs = 30000 );//::  * **$*** \n 
	QString workingDirectory () const; //::  * **$*** \n 
		//::====Наследованные слоты и сигналы от QProcess====
		//::===Public Slots===
		//::  * **void kill ()**
		//::  * **void terminate ()**
		//::===Signals===
		//::  * **void error ( QProcess::ProcessError error )**
		//::  * **void finished ( int exitCode, QProcess::ExitStatus exitStatus )**
		//::  * **void readyReadStandardError ()**
		//::  * **void readyReadStandardOutput ()**
		//::  * **void started ()**
		//::  * **void stateChanged ( QProcess::ProcessState newState )**
		// see also: state()
	
        QStringList systemEnvironment (); //::* **$***

	//::====Публичные наследованные функции от QIODevice`s====
	bool getChar ( char * c ); 			//::  * **$***  
	QByteArray read ( qint64 maxSize );		//::  * **$*** 
	QByteArray readAll ();				//::  * **$*** 
	QByteArray readLine ( qint64 maxSize = 0 );	//::  * **$*** 
	qint64 write ( const QByteArray & byteArray );	//::  * **$*** 
			// "const QByteArray &" !!! simple "QByteArray"  not working well
	//qint64 write ( const QString & _string );
		//::===Signals===
		//::  * **void aboutToClose ()**
		//::  * **void bytesWritten ( qint64 bytes )**
		//::  * **void readChannelFinished ()**
		//::  * **void readyRead ()**
	
		bool waitForReadyRead ( int msecs = 1000 );//::  * **$*** 
	//bool waitForBytesWritten ( int msecs );
/*?*/	
	qint64 bytesAvailable();//::  * **$*** \n Отдает количество байт доступных для считывания на потоках вывода и ошибок от дочернего канала.
/*?*/	//qint64 bytesToWrite () const;

	QString errorString () const;//::  * **$*** 


};

//----------------------------------------------------------------------
//нужно чтобы можно было передавать эти элементы как параметры в функции внутри QtScript
// спец. настройки для QtScript (v 2008.11.25)
// Шаг 3 из 8
Q_DECLARE_METATYPE(qdl_ChildProcess*);

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 4 из 8
static QScriptValue f_qdroid_qdl_ChildProcess_toScriptValue(QScriptEngine *engine, qdl_ChildProcess* const &in)
{ return engine->newQObject(in); }

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 5 из 8
static void f_qdroid_qdl_ChildProcess_fromScriptValue(const QScriptValue &object, qdl_ChildProcess* &out)
{ out = qobject_cast<qdl_ChildProcess*>(object.toQObject()); }

// спец. настройки для QtScript (v 2008.11.25)
// Шаг 6 из 8
//конструктор для последующего его определения как new в скрипте
static QScriptValue f_qdroid_qdl_ChildProcess_constructor(QScriptContext *QSContext, QScriptEngine *QSEngine)
	{
		//t_BaseBot BaseBot;
		QScriptValue QtSObject;
		QtSObject=QSEngine->newQObject(new qdl_ChildProcess()); //
		return QtSObject;
	}

// шаги 7 и 8 должны быть выполнены в программе которая собирается использовать данный класс совместно со скриптовым движком
//// спец. настройки для QtScript (v 2008.11.25)
//// Шаг 7 из 8
//// - это qScriptRegisterMetaType регистрация но это нужно сделать в головном классе
//// например в глобальной функции "define__qdroid_qtscript_functions()"
////// t_FileList TYPE defenition
//	qScriptRegisterMetaType(_QSEngine, f_qdroid_qdl_ChildProcess_toScriptValue, f_qdroid_qdl_ChildProcess_fromScriptValue);

//// спец. настройки для QtScript (v 2008.11.25)
//// Шаг 8 из 8
////- определение конструктора в контексте скрипта
////// t_FileList NEW constructor defenition
//	QScriptValue fun5_constr = _QSEngine->newFunction(f_qdroid_qdl_ChildProcess_constructor);
//	_QSEngine->globalObject().setProperty("qdl_ChildProcess", fun5_constr);

static int f_qdroid_extention_class_register(QScriptEngine *_QSEngine)
	{
		//шаг 7 регистрация метатипа
		qScriptRegisterMetaType(_QSEngine, f_qdroid_qdl_ChildProcess_toScriptValue, f_qdroid_qdl_ChildProcess_fromScriptValue);
		//шаг 8 регистрация конструктора
		_QSEngine->globalObject().setProperty("ChildProcess", _QSEngine->newFunction(f_qdroid_qdl_ChildProcess_constructor));
		return 0;
	}

/*
qdl_ChildProcess *f_qdroid_extention_class_constructor()
	{
		return new qdl_ChildProcess();
	}
*/
//----------------------------------------------------------------------

#endif /* SIMPLE_BOT_H_ */
